#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys,os
import urllib
import sgmllib

#DIF:(EMA(CLOSE,SHORT)-EMA(CLOSE,LONG))*100;
#DEA:EMA(DIF,MID);
#MACD:(DIF-DEA)*2,COLORSTICK;
#RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100;
#K:SMA(RSV,M1,1);
#D:SMA(K,M2,1);
#J:3*K-2*D;

#HHV(X,N)是求N周期内X最高值
#LLV(X,N)是求N周期内X最低值

#MA(X,N),求X的N日移动平均值。算法：(X1+X2+X3+...+Xn)/N
#EMA(X,N),求X的N日指数平滑移动平均, Y=[2*X+(N-1)*Y']/(N+1), 其中Y 表示上一周期Y值 
#SMA(X,N,M),求X的N日移动平均,M为权重, Y=[M*X+(N-M)*Y')/N, 其中Y 表示上一周期Y值, N必须大于M
#DMA(X,A),求X的动态移动平均, Y=A*X+(1-A)*Y',27h,',其中Y 表示上一周期Y值,A必须小1

def get_int(data):
    ret = ord(data[0])+(ord(data[1])<<8)+(ord(data[2])<<16)+(ord(data[3])<<24)
    return ret
    
class StockData():
    OPEN = float(0)
    CLOSE = float(0)
    LOW = float(0)
    HIGH = float(0)
    AMOUNT = ''
    def __init__(self, code):
        params = urllib.urlencode({'code':code})
        hd = urllib.urlopen(sohu_stock_url+'?%s' % params)
        parser = MyHTMLParser()
        content = hd.read()
        data = content.decode('gb2312').encode('utf8')
        parser.feed(data)
        (open, close, low, high, amount) = parser.get_data()
        self.OPEN = float(open)
        self.CLOSE = float(close)
        self.LOW = float(low)
        self.HIGH = float(high)
        self.AMOUNT = amount

class stockdatabase:
    def __init__(self):
        self.DAY = []
        self.OPEN = []
        self.CLOSE = []
        self.LOW = []
        self.HIGH = []
        self.AMOUNT = []
    def append(self, day, dopen, dclose, dlow, dhigh, damount):
        self.DAY.append(day)
        self.OPEN.append(dopen)
        self.CLOSE.append(dclose)
        self.LOW.append(dlow)
        self.HIGH.append(dhigh)
        self.AMOUNT.append(damount)

class MA:
    def _ma(self, database, index, N):
        ret = nsum = float(0)
        if (index >= N):
            for i in range(N):
                nsum = nsum+database[index-i]
                ret = nusm/N
        return ret
    def __init__(self, database, N):
        self.data = []
        for i in range(len(database)):
            ret = self._ma(database, i, N)
            self.data.append(ret)
class SMA:
    def _sma(self, database, index, N, M):
        ret = float(0)
        if (index >= 2):
            ret = (M*database[index]+self.data[index-1]*(N-M))/N
        elif (index == 1):
                ret = database[index]
        return ret
        
    def __init__(self, database, N, M):
        self.data = []
        for i in range(len(database)):
            ret = self._sma(database, i, N, M)
            self.data.append(ret)

class EMA:
    def _ema(self, database, index, N):
        ret = float(0)
        if (index >= 2):
            ret = (2*database[index] + (N-1)*self.data[index-1])/(N+1)
        elif (index == 1):
            ret = database[index]
        return ret
    def __init__(self, database, N):
        self.data = []
        for i in range(len(database)):
            ret = self._ema(database, i, N)
            self.data.append(ret)

class HHV:
    def _hhv(self, database, index, N):
        i = index
        ret = database[i]
        while (i >= 0) and (i>=(index+1-N)):
            if database[i] > ret:
                ret = database[i]
            i = i-1
        return ret        
    def __init__(self, database, N):
        self.data = []
        for i in range(len(database)):
            ret = self._hhv(database, i, N)
            self.data.append(ret)
            
class LLV:
    def _llv(self, database, index, N):
        i = index
        ret = database[i]
        while (i >= 0) and (i>=(index+1-N)):
            if database[i] < ret:
                ret = database[i]
            i = i-1
        return ret   
    def __init__(self, database, N):
        self.data = []
        for i in range(len(database)):
            ret = self._llv(database, i, N)
            self.data.append(ret)

class RSV:
    def __init__(self, database, N):
        self.data = []
        llvn = LLV(database.LOW, N)
        hhvn = HHV(database.HIGH, N)
        for i in range(len(database.LOW)):
            try:
                ret = (database.CLOSE[i]-llvn.data[i])/(hhvn.data[i]-llvn.data[i])*100
            except ZeroDivisionError:
                self.data.append(0)
            else:
                self.data.append(ret)

class KDJ:
    def __init__(self, database, N, M1, M2):
        self.dataJ = []
        rsvn = RSV(database, N)
        tmp = SMA(rsvn.data, M1, 1)
        self.dataK = tmp.data 
        tmp = SMA(self.dataK, M2, 1)
        self.dataD = tmp.data
        for i in range(len(rsvn.data)):
            ret = 3*self.dataK[i]-2*self.dataD[i]
            self.dataJ.append(ret)
class MACD:
    def __init__(self, database, SHORT, LONG, M):
        emas = EMA(database.CLOSE, SHORT)
        emal = EMA(database.CLOSE, LONG)
        self.dataDIF = []
        self.dataMACD = []
        for i in range(len(emas.data)):
            ret = (emas.data[i] - emal.data[i])
            self.dataDIF.append(ret)
        tmp = EMA(self.dataDIF, M)
        self.dataDEA = tmp.data
        for i in range(len(self.dataDEA)):
            ret = (self.dataDIF[i]-self.dataDEA[i])*2
            self.dataMACD.append(ret)

def do_parse(file):
    ret = stockdatabase()
    fp = open(file, 'rb')
    data = fp.read(40)
    while data and len(data)==40:
        str_date       = data[  :4 ]
        DATE = get_int(str_date)

        str_open_price = data[4 :8 ]
        OPEN = get_int(str_open_price)/float(1000)

        str_high_price  = data[8 :12]
        HIGH = get_int(str_high_price)/float(1000)

        str_low_price  = data[12:16]
        LOW = get_int(str_low_price)/float(1000)

        str_close_price= data[16:20]
        CLOSE = get_int(str_close_price)/float(1000)

        str_moneysum = data[20:24]
        MONEYSUM = get_int(str_moneysum)/float(1000)

        str_amount = data[24:28]
        AMOUNT = get_int(str_amount)

        # create a data object of the day
        day = ret.append(DATE, OPEN, CLOSE, LOW, HIGH, AMOUNT)

        data = fp.read(40)
    return ret
